#include <iostream>
#include "clips.h"
#include <client/dbclient.h>
extern std::list<std::string> rmatch;
void alert()
{
    using namespace std;
    DATA_OBJECT temp;
    int args=RtnArgCount();
    if(args!=1)
    {
        return;
    }
    if(ArgTypeCheck("alert",1,SYMBOL_OR_STRING,&temp)==0)
    {
        return;
    }
    string rname=RtnLexeme(1);
    rmatch.push_back(rname);
}

int rdbcount()
{
    using namespace std;
    using namespace mongo;
    DATA_OBJECT temp;
    string dbaddr,collection,bjson,oid,keyoid;
    int args=RtnArgCount();
    if(args!=5)
    {
        return(-1);
    }
    dbaddr=RtnLexeme(1);
    collection=RtnLexeme(2);
    bjson=RtnLexeme(3);
    keyoid=RtnLexeme(4);
    oid=RtnLexeme(5);
    DBClientConnection c;
    BSONObj bj,q;
    BSONObjBuilder x;
    try
    {
        bj=fromjson(bjson);
        x.appendElements(bj);
        x.append(keyoid,OID(oid));
        q=x.obj();
        c.connect(dbaddr);
    }
    catch(DBException e)
    {
        return(-1);
    }
    auto_ptr<DBClientCursor> cursor;
    try
    {
        cursor=c.query(collection,q);
    }
    catch(DBException e)
    {
        return(-1);
    }
    int count=cursor->itcount();
    return(count);
}
void * dbquery()
{
    using namespace std;
    using namespace mongo;
    DATA_OBJECT temp;
    void *returnvalue;
    string dbaddr,collection,q,ret;
    //BSONObjBuilder b; 
    BSONObj *x;
    int args=RtnArgCount();
    if(args!=3)
    {
        return(NULL);
    }
    dbaddr=RtnLexeme(1);
    collection=RtnLexeme(2);
    DBClientConnection c;
    try
    {
        c.connect(dbaddr);
    }
    catch(DBException e)
    {
        return(NULL);
    }
    q=RtnLexeme(3);
    auto_ptr<DBClientCursor> cursor;
    try
    {
        cursor=c.query(collection,Query(q),1);
    }
    catch(DBException e)
    {
        return(NULL);
    }
    if(cursor->more())
    {
        x=new BSONObj(cursor->next().getOwned());
        std::cout<<x->toString()<<endl;
        return((void *)x);
    }
    else
    {
        return(NULL);
    }
}
    
void destructQuery()
{
    using namespace mongo;
    int args=RtnArgCount();
    DATA_OBJECT temp;
    if(args!=1)
    {
        return;
    }
    RtnUnknown(1,&temp);
    void * x=DOToPointer(temp);
    if(x==NULL)
    {
        return;
    }
    BSONObj *b=(BSONObj *)x;
    delete b;
    x=NULL;
}
int findInt()
{
    using namespace mongo;
    if(ArgCountCheck("findString",EXACTLY,2)==-1)
    {
        return(-1);
    }
    DATA_OBJECT temp;
    RtnUnknown(1,&temp);
    BSONObj *b=(BSONObj *)DOToPointer(temp);
    string key=RtnLexeme(2);
    BSONElement v=b->getFieldDotted(key);
    if(v.type()==NumberInt)
    {
        return(v.numberInt());
    }
    return(-1);
}
void * findString()
{
    using namespace mongo;
    if(ArgCountCheck("findString",EXACTLY,2)==-1)
    {
        return(AddSymbol(""));
    }
    DATA_OBJECT temp;
    RtnUnknown(1,&temp);
    BSONObj *b=(BSONObj *)DOToPointer(temp);
    string key=RtnLexeme(2);
    BSONElement v=b->getFieldDotted(key);
    char buff[1024];
    strcpy(buff,v.str().c_str());
    if(v.type()==String)
    {
       
        return(AddSymbol(buff));

    }

    return(AddSymbol("#Invalid type"));
    /*
    switch(v.type())
    {
        case String:
        SetpType(returnValuePtr,STRING);
        strcpy(buff,v.str().c_str());
        SetpValue(returnValuePtr,buff);
        return;
        case NumberDouble:
        //SetpType(returnValuePtr,FLOAT);
        numf=v.numberDouble();
        AddDouble(numf);
        //SetpValue(returnValuePtr,numf);
        return;
        case NumberInt:
        SetpType(returnValuePtr,INTEGER);
        numi=v.numberInt();
        SetpValue(returnValuePtr,numi);
        return;
     }*/
}

int dbcount()
{
    using namespace std;
    using namespace mongo;
    DATA_OBJECT temp;
    string dbaddr,collection;
    int args=RtnArgCount();
    if(args!=3) 
    {
        return(-1);
    }
    dbaddr=RtnLexeme(1);
    collection=RtnLexeme(2);
    DBClientConnection c;
    try
    {
        c.connect(dbaddr);
    }catch(DBException e)
    {
        return(-1);
    }
    string bjson=RtnLexeme(3);
    
    //BSONObj q=fromjson(bjson);
    //cout<<q.toString()<<endl;
    auto_ptr<DBClientCursor> cursor;
    try{
        cursor=c.query(collection,Query(bjson));
    }
    catch(DBException e)
    {
        return(-1);
    }
    int count=cursor->itcount();
    return(count);
}
